import requests
import random
import time
from datetime import datetime, timedelta

from environs import Env
from selenium.webdriver.common.by import By

import browser as browser_


env = Env()
env.read_env()

ADMIN_ID = env.int('ADMIN_ID')
BOT_TOKEN = env.str('BOT_TOKEN')


def get_time_of_desired_format(time):
    """ Получаем время нужного формата """

    return time.strftime('%I:%M:%S%p %A, %d %B %Y')


def set_delay(a=60, b=90):
    """ Получаем время для задержки """

    time_seconds = random.randint(a, b)
    time_of_next_parsing = get_time_of_desired_format(datetime.now() + timedelta(seconds=time_seconds))
    print(f'Time of the next parsing - {time_of_next_parsing}')
    print(f'Waiting {time_seconds} seconds...')
    time.sleep(time_seconds)


def get_start_time_of_parser():
    """ Получаем время запуска парсера """

    current_time = get_time_of_desired_format(datetime.now())
    print(f'\nParsing starts at - {current_time}')
    return current_time


def close_browser(browser):
    """ Закрываем браузер """

    browser.close()
    browser.quit()


def get_browser():
    """ Получаем браузер """

    browser = browser_object.get_browser()


def get_all_orders():
    """ Получаем все заказы """

    list_of_all_orders = []

    with open('all_orders.txt') as file:
        for line in file:
            order = line.strip()
            list_of_all_orders.append(order)

    return list_of_all_orders


def get_orders_from_page(browser):
    """ Получаем все заказы """

    list_of_orders = {}
    orders = browser.find_elements(
        By.XPATH,
        '//div[@class="task__title"]/a'
    )

    for number, order in enumerate(orders, 0):
        link = order.get_attribute('href')
        title = order.text
        list_of_orders[number] = {'link': link, 'title': title}

    return list_of_orders


def get_new_orders(orders_from_page):
    """ Получаем новые заказы """

    all_orders = get_all_orders()
    list_of_new_orders = []

    for order in orders_from_page.values():
        if order['link'] in all_orders: continue
        list_of_new_orders.append(order)

    return list_of_new_orders


def add_new_orders(new_orders):
    """ Добавляем новые заказы """

    if not new_orders: return

    with open('all_orders.txt', 'a') as file:
        for order in new_orders:
            file.write(order['link'] + '\n')


def report_new_orders(new_orders):
    """ Сообщаем о новых заказах """

    for order in new_orders:
        link = f'https://api.telegram.org/bot{BOT_TOKEN}/sendMessage?chat_id={ADMIN_ID}&text={order["link"]}'
        requests.get(link)


def start_parsing():
    """ Начинаем парсинг """

    def preforme_initial_actions(browser_object):
        """ Выполняем начальные действия """

        browser = browser_object.get_browser()
        browser.get(link_freelance_habr)
        return browser


    def preforme_final_actions(browser_object, browser, count, new_orders, start_time_of_parser):
        """ Выполняем завершающие действия """

        def show_new_orders(new_orders):
            """ Показать новые заказы """

            if new_orders:
                for number, order in enumerate(new_orders, 0):
                    message = f"\n  {number}: {order['title']}\n  {order['link']}"
                    print(message)
            else:
                print('\n  No new orders found')


        def show_iteration_number(count):
            """ Показываем номер итерации """

            print(f'Iteration number - {count}')


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        browser_object.close_browser(browser)
        show_new_orders(new_orders)
        print(f'\nParsing starts at - {start_time_of_parser}')
        show_iteration_number(count)
        set_delay()


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    browser_object = browser_.Browser()
    count = 0
    start_time_of_parser = get_start_time_of_parser()
    link_freelance_habr = 'https://freelance.habr.com/tasks?categories=development_all_inclusive,development_backend, \
                           development_frontend,development_bots,development_scripts,development_other'

    while True:
        browser = preforme_initial_actions(browser_object)

        orders_from_page = get_orders_from_page(browser)
        new_orders = get_new_orders(orders_from_page)
        add_new_orders(new_orders)
        report_new_orders(new_orders)

        preforme_final_actions(browser_object, browser, count, new_orders, start_time_of_parser)
        count += 1


def main():
    try:
        start_parsing()
    except KeyboardInterrupt:
        print('\n\nThe parser is stopped\n')


if __name__ == '__main__':
    main()
